function [G, new_H, Hvv, Hsvals, Gsvals] = compute_G_from_H(H)
    
    %%% main %%%
    mdimG = 2;
    [n_samples, ~, n_dim] = size(H);
    Huu = zeros(n_samples, n_dim, n_dim);
    Hsvals = zeros(n_samples, n_dim, n_dim);
    Hvv = zeros(n_samples, n_dim, n_dim);
    parfor ii = 1: n_samples
        [Huu(ii, :, :), Hsvals(ii, :, :), Hvv(ii, :, :)] = svd(squeeze(H(ii, :, :)));
    end
    Gsvals = zeros(size(Hsvals));
    if isempty(mdimG) || mdimG == n_dim
        idt = Hsvals ~= 0;
        Gsvals(idt) = 1 ./ Hsvals(idt);
        G = zeros(n_samples, n_dim, n_dim);
        new_H = H;
        for i = 1: n_samples
            G(i, :, :) = squeeze(Huu(i, :, :)) * squeeze(Gsvals(i, :, :)) * squeeze(Hvv(i, :, :));
        end
    elseif mdimG < n_dim
        Hvtmp = Hsvals(:, 1: mdimG, 1: mdimG);
        idt = tmp ~= 0;
        Gstmp = zeros(size(Hvtmp));
        Gstmp(idt) = 1 ./ Hvtmp(idt);
        Gsvals(:, 1: mdimG, 1: mdimG) = Gstmp;
        G = zeros(n_samples, mdimG, mdimG);
        new_H = zeros(n_samples, mdimG, mdimG);
        for i = 1: n_samples
            G(i, 1: mdimG, 1: mdimG) = squeeze(Huu(i, :, mdimG)) * squeeze(Gsvals(i, 1: mdimG, 1: mdimG)) * squeeze(Hvv(i, :, 1: mdimG));
            new_H(i, :, 1: mdimG) = squeeze(Huu(i, :, mdimG)) * squeeze(Hsvals(i, 1: mdimG, 1: mdimG)) * squeeze(Hvv(i, :, 1: mdimG));
        end
    end
end


